//
//  NetQueue.cpp
//  FreeNet
//
//  Created by cc on 12-7-5.
//  Copyright (c) 2012年 cc. All rights reserved.
//

#include "NetQueue.h"

namespace FreeNet {
    
    const int _queue_max = 10 ;
    const int _queue_size_max = 8 * 1024 ;
    struct sMsgQueue
    {
        bool unused ;
        int _head, _tail ;
        int _size, _max ;
        char _data[_queue_size_max] ;
    } ;
    sMsgQueue msgQueue[_queue_max] ;
    int _queue_index = 0 ;
    void resetMsgQueue(const int index) ;
    void resetMsgQueue(const int index)
    {
        assert(0 <= index && _queue_max > index) ;
        msgQueue[index].unused = true ;
        msgQueue[index]._head = 0 ;
        msgQueue[index]._tail = 0 ;
        msgQueue[index]._size = 0 ;
        msgQueue[index]._max = _queue_size_max ;
        ::memset(msgQueue[index]._data, 0, _queue_size_max) ;
    }

    int createQueue(const int max)
    {
        if (_queue_max <= _queue_index)
        {
            return -1 ;
        }
        resetMsgQueue(_queue_index) ;
        msgQueue[_queue_index].unused = false ;
        return (_queue_index++) ;
    }

    int destroyQueue(const int index)
    {
        if (0 > index || _queue_max <= index)
        {
            return -1 ;
        }
        resetMsgQueue(_queue_index) ;
        msgQueue[index].unused = true ;
        return index ;
    }

    bool checkQueueFull(const int index)
    {
        if (msgQueue[index].unused)
        {
            return false ;
        }

        return ((msgQueue[index]._size+1024) >= msgQueue[index]._max) ;
    }

    void* popData(const int index, const int len)
    {
        if (0 > index || _queue_max <= index)
        {
            return 0 ;
        }
        sMsgQueue* pMsg = &(msgQueue[index]) ;
        if (0 >= pMsg->_size)
        {
            return 0 ;
        }
        if (len > pMsg->_size)
        {
            return 0 ;
        }

        char* res = new char[len+1] ;
        ::memset(res, 0, len+1) ;
        ::memcpy(res, pMsg->_data, len) ;
        ::memcpy(pMsg->_data, &(pMsg->_data[len]), (pMsg->_max-1)-len) ;
        pMsg->_size -= len ;
        return res ;
    }

    int pushData(const int index, const void* data, const int len)
    {
        if (0 > index || _queue_max <= index)
        {
            return -1 ;
        }
        sMsgQueue* pMsg = &(msgQueue[index]) ;
        if (pMsg->_max < (pMsg->_size + len))
        {
            ::printf("NetQueue.cpp pushData buffer is full \n") ;
            return -1 ;
        }
        ::memcpy(&(pMsg->_data[pMsg->_size]), data, len) ;
        pMsg->_size += len ;

        return len ;
    }
}


































